#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

static char gpio_path[100];

static int gpio_config(const char *attr, const char *val)
{
    char file_path[100];
    int len;
    int fd;

    //把要控制的那个设备文件名字和写入的状态参数，写入到字符串中
    sprintf(file_path,"%s/%s",gpio_path,attr);

    //打开这个字符串
    fd = open(file_path,O_WRONLY);
    if(fd < 0){
        perror("open error");
        return fd;
    }

    //往打开到文件中写入val的值
    len = strlen(val);
    if(len != write(fd,val,len)){
        perror("write error");
        close(fd);
        return -1;
    }

    //关闭文件
    close(fd);
    return 0;
}

/*  主函数  */
int main(int argc,char *argv[])
{
    char file_path[100];
    char val;
    int fd;

    /*  校验传参  */
    if(2 != argc){
       fprintf(stderr,"usage:%s<gpio>\n",argv[0]);
       exit(-1); 
    }

    /*  判断指定编号到gpio是否导出 */
    sprintf(gpio_path,"/sys/class/gpio/gpio%s",argv[1]);

    //如果这个目录不存在，需要导出
    if(access(gpio_path,F_OK)){
        int len;
        
        //打开路径文件
        fd = open("/sys/class/gpio/export",O_WRONLY);
        if(fd < 0){
            perror("open error");
            exit(-1);
        }

        len = strlen(argv[1]);
        if(len != write(fd,argv[1],len)){
            perror("write error");
            close(fd);
            exit(-1);
        }
        close(fd);

        /*  配置为输入模式  */
        if(gpio_config("direction","in"))
            exit(-1);

        /*  极性设置  */
        if(gpio_config("active_low","0"))
            exit(-1);

        /*  配置为非中断模式    */
        if(gpio_config("edge","none"))
            exit(-1);

        /*  读取GPIO电平状态    */
        sprintf(file_path,"%s/%s",gpio_path,"value");

        if(0 > (fd = open(file_path,O_RDONLY))){
            perror("open error");
            exit(-1);
        }

        if(0 > read(fd,&val,1)){
            perror("read error");
            close(fd);
            exit(-1);
        }

        printf("value:%c\n",val);

        /*  退出程序    */
        close(fd);
        exit(0);

        
    }
}